fix to properly queue resizes when the image is set
authorHavoc Pennington <hp@redhat.com>
Wed, 18 Apr 2001 18:09:18 +0000 (18:09 +0000)
committerHavoc Pennington <hp@src.gnome.org>
Wed, 18 Apr 2001 18:09:18 +0000 (18:09 +0000)
2001-04-18  Havoc Pennington  <hp@redhat.com>

* gtk/gtkimage.c: fix to properly queue resizes when the image is
set

* gtk/gtktextview.c (gtk_text_view_do_popup): desensitize Paste
if the insertion point isn't editable

* demos/gtk-demo/images.c: Added a GtkImage demo

* demos/gtk-demo/drawingarea.c: drawing area demo

* demos/gtk-demo/menus.c (create_menu): cleanups

2001-04-18  Havoc Pennington  <hp@redhat.com>

* gdk-pixbuf.c (gdk_pixbuf_fill): Function to fill pixbuf with a
given color.

33 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
demos/gtk-demo/Makefile.am
demos/gtk-demo/apple-red.png [new file with mode: 0644]
demos/gtk-demo/background.jpg [new file with mode: 0644]
demos/gtk-demo/button_box.c
demos/gtk-demo/drawingarea.c [new file with mode: 0644]
demos/gtk-demo/gnome-applets.png [new file with mode: 0644]
demos/gtk-demo/gnome-calendar.png [new file with mode: 0644]
demos/gtk-demo/gnome-foot.png [new file with mode: 0644]
demos/gtk-demo/gnome-gimp.png [new file with mode: 0644]
demos/gtk-demo/gnome-gmush.png [new file with mode: 0644]
demos/gtk-demo/gnome-gsame.png [new file with mode: 0644]
demos/gtk-demo/gnu-keys.png [new file with mode: 0644]
demos/gtk-demo/gtk-logo-rgb.gif [new file with mode: 0644]
demos/gtk-demo/images.c [new file with mode: 0644]
demos/gtk-demo/main.c
demos/gtk-demo/menus.c
demos/gtk-demo/pixbufs.c [new file with mode: 0644]
demos/pixbuf-demo.c
docs/reference/gtk/tmpl/gtk-unused.sgml
docs/reference/gtk/tmpl/gtkrc.sgml
docs/reference/gtk/tmpl/gtktextview.sgml
gdk-pixbuf/ChangeLog
gdk-pixbuf/gdk-pixbuf.c
gdk-pixbuf/gdk-pixbuf.h
gtk/gtkimage.c
gtk/gtktextview.c

index 1d1b3753e2b0c11fa3bc3bc15b40cbc7690c3629..b984620d1e4d70963b986c4a966839443e023c31 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2001-04-18  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtkimage.c: fix to properly queue resizes when the image is
+       set
+
+       * gtk/gtktextview.c (gtk_text_view_do_popup): desensitize Paste
+       if the insertion point isn't editable
+
+       * demos/gtk-demo/images.c: Added a GtkImage demo
+
+       * demos/gtk-demo/drawingarea.c: drawing area demo
+       
+       * demos/gtk-demo/menus.c (create_menu): cleanups
+
 Wed Apr 18 12:15:52 2001  Owen Taylor  <otaylor@redhat.com>
 
        * gdk/x11/gdkwindow-x11.c gdk/x11/gdkwindow-x11.h 
index 1d1b3753e2b0c11fa3bc3bc15b40cbc7690c3629..b984620d1e4d70963b986c4a966839443e023c31 100644 (file)
@@ -1,3 +1,17 @@
+2001-04-18  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtkimage.c: fix to properly queue resizes when the image is
+       set
+
+       * gtk/gtktextview.c (gtk_text_view_do_popup): desensitize Paste
+       if the insertion point isn't editable
+
+       * demos/gtk-demo/images.c: Added a GtkImage demo
+
+       * demos/gtk-demo/drawingarea.c: drawing area demo
+       
+       * demos/gtk-demo/menus.c (create_menu): cleanups
+
 Wed Apr 18 12:15:52 2001  Owen Taylor  <otaylor@redhat.com>
 
        * gdk/x11/gdkwindow-x11.c gdk/x11/gdkwindow-x11.h 
index 1d1b3753e2b0c11fa3bc3bc15b40cbc7690c3629..b984620d1e4d70963b986c4a966839443e023c31 100644 (file)
@@ -1,3 +1,17 @@
+2001-04-18  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtkimage.c: fix to properly queue resizes when the image is
+       set
+
+       * gtk/gtktextview.c (gtk_text_view_do_popup): desensitize Paste
+       if the insertion point isn't editable
+
+       * demos/gtk-demo/images.c: Added a GtkImage demo
+
+       * demos/gtk-demo/drawingarea.c: drawing area demo
+       
+       * demos/gtk-demo/menus.c (create_menu): cleanups
+
 Wed Apr 18 12:15:52 2001  Owen Taylor  <otaylor@redhat.com>
 
        * gdk/x11/gdkwindow-x11.c gdk/x11/gdkwindow-x11.h 
index 1d1b3753e2b0c11fa3bc3bc15b40cbc7690c3629..b984620d1e4d70963b986c4a966839443e023c31 100644 (file)
@@ -1,3 +1,17 @@
+2001-04-18  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtkimage.c: fix to properly queue resizes when the image is
+       set
+
+       * gtk/gtktextview.c (gtk_text_view_do_popup): desensitize Paste
+       if the insertion point isn't editable
+
+       * demos/gtk-demo/images.c: Added a GtkImage demo
+
+       * demos/gtk-demo/drawingarea.c: drawing area demo
+       
+       * demos/gtk-demo/menus.c (create_menu): cleanups
+
 Wed Apr 18 12:15:52 2001  Owen Taylor  <otaylor@redhat.com>
 
        * gdk/x11/gdkwindow-x11.c gdk/x11/gdkwindow-x11.h 
index 1d1b3753e2b0c11fa3bc3bc15b40cbc7690c3629..b984620d1e4d70963b986c4a966839443e023c31 100644 (file)
@@ -1,3 +1,17 @@
+2001-04-18  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtkimage.c: fix to properly queue resizes when the image is
+       set
+
+       * gtk/gtktextview.c (gtk_text_view_do_popup): desensitize Paste
+       if the insertion point isn't editable
+
+       * demos/gtk-demo/images.c: Added a GtkImage demo
+
+       * demos/gtk-demo/drawingarea.c: drawing area demo
+       
+       * demos/gtk-demo/menus.c (create_menu): cleanups
+
 Wed Apr 18 12:15:52 2001  Owen Taylor  <otaylor@redhat.com>
 
        * gdk/x11/gdkwindow-x11.c gdk/x11/gdkwindow-x11.h 
index 1d1b3753e2b0c11fa3bc3bc15b40cbc7690c3629..b984620d1e4d70963b986c4a966839443e023c31 100644 (file)
@@ -1,3 +1,17 @@
+2001-04-18  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtkimage.c: fix to properly queue resizes when the image is
+       set
+
+       * gtk/gtktextview.c (gtk_text_view_do_popup): desensitize Paste
+       if the insertion point isn't editable
+
+       * demos/gtk-demo/images.c: Added a GtkImage demo
+
+       * demos/gtk-demo/drawingarea.c: drawing area demo
+       
+       * demos/gtk-demo/menus.c (create_menu): cleanups
+
 Wed Apr 18 12:15:52 2001  Owen Taylor  <otaylor@redhat.com>
 
        * gdk/x11/gdkwindow-x11.c gdk/x11/gdkwindow-x11.h 
index 1d1b3753e2b0c11fa3bc3bc15b40cbc7690c3629..b984620d1e4d70963b986c4a966839443e023c31 100644 (file)
@@ -1,3 +1,17 @@
+2001-04-18  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtkimage.c: fix to properly queue resizes when the image is
+       set
+
+       * gtk/gtktextview.c (gtk_text_view_do_popup): desensitize Paste
+       if the insertion point isn't editable
+
+       * demos/gtk-demo/images.c: Added a GtkImage demo
+
+       * demos/gtk-demo/drawingarea.c: drawing area demo
+       
+       * demos/gtk-demo/menus.c (create_menu): cleanups
+
 Wed Apr 18 12:15:52 2001  Owen Taylor  <otaylor@redhat.com>
 
        * gdk/x11/gdkwindow-x11.c gdk/x11/gdkwindow-x11.h 
index 6fa87fac727cd1de20265d650562fcf52b66fdbd..b581f51e1483e0d9a718e9c3694bdcb0c1d2b4d5 100644 (file)
@@ -2,12 +2,17 @@
 
 democodedir=$(datadir)/gtk-2.0/demo
 
+## These should be in the order you want them to appear in the 
+## demo app, which means alphabetized by demo title, not filename
 demos = @STRIP_BEGIN@  \
        button_box.c    \
+       dialog.c        \
+       drawingarea.c   \
+       images.c        \
        item_factory.c  \
        menus.c         \
        panes.c         \
-       dialog.c        \
+       pixbufs.c       \
        textview.c      \
 @STRIP_END@
 
@@ -63,4 +68,17 @@ gtk_demo_SOURCES =           \
 gtk_demo_DEPENDENCIES = $(DEPS)
 gtk_demo_LDADD = $(LDADDS)
 
-democode_DATA = $(demos)
+IMAGEFILES=    apple-red.png           \
+               background.jpg          \
+               gnome-applets.png       \
+               gnome-calendar.png      \
+               gnome-foot.png          \
+               gnome-gimp.png          \
+               gnome-gmush.png         \
+               gnome-gsame.png         \
+               gnu-keys.png            \
+               gtk-logo-rgb.gif
+
+democode_DATA = $(demos) $(IMAGEFILES)
+
+EXTRA_DIST = $(IMAGEFILES)
diff --git a/demos/gtk-demo/apple-red.png b/demos/gtk-demo/apple-red.png
new file mode 100644 (file)
index 0000000..b0a24e9
Binary files /dev/null and b/demos/gtk-demo/apple-red.png differ
diff --git a/demos/gtk-demo/background.jpg b/demos/gtk-demo/background.jpg
new file mode 100644 (file)
index 0000000..86c006a
Binary files /dev/null and b/demos/gtk-demo/background.jpg differ
index a0fae1122606b37145ea37078bce7d5a229b83b8..f8e7bd3838da31ddb642e6a3c305651b588c0c5b 100644 (file)
@@ -72,19 +72,19 @@ do_button_box (void)
     gtk_container_add (GTK_CONTAINER (frame_horz), vbox);
 
     gtk_box_pack_start (GTK_BOX (vbox), 
-          create_bbox (TRUE, "Spread", 40, GTK_BUTTONBOX_SPREAD),
+                        create_bbox (TRUE, "Spread", 40, GTK_BUTTONBOX_SPREAD),
                        TRUE, TRUE, 0);
 
     gtk_box_pack_start (GTK_BOX (vbox), 
-          create_bbox (TRUE, "Edge", 40, GTK_BUTTONBOX_EDGE),
+                        create_bbox (TRUE, "Edge", 40, GTK_BUTTONBOX_EDGE),
                        TRUE, TRUE, 5);
-
+    
     gtk_box_pack_start (GTK_BOX (vbox), 
-          create_bbox (TRUE, "Start", 40, GTK_BUTTONBOX_START),
+                        create_bbox (TRUE, "Start", 40, GTK_BUTTONBOX_START),
                        TRUE, TRUE, 5);
-
+    
     gtk_box_pack_start (GTK_BOX (vbox), 
-          create_bbox (TRUE, "End", 40, GTK_BUTTONBOX_END),
+                        create_bbox (TRUE, "End", 40, GTK_BUTTONBOX_END),
                        TRUE, TRUE, 5);
 
     frame_vert = gtk_frame_new ("Vertical Button Boxes");
@@ -95,19 +95,19 @@ do_button_box (void)
     gtk_container_add (GTK_CONTAINER (frame_vert), hbox);
 
     gtk_box_pack_start (GTK_BOX (hbox), 
-          create_bbox (FALSE, "Spread", 30, GTK_BUTTONBOX_SPREAD),
+                        create_bbox (FALSE, "Spread", 30, GTK_BUTTONBOX_SPREAD),
                        TRUE, TRUE, 0);
 
     gtk_box_pack_start (GTK_BOX (hbox), 
-          create_bbox (FALSE, "Edge", 30, GTK_BUTTONBOX_EDGE),
+                        create_bbox (FALSE, "Edge", 30, GTK_BUTTONBOX_EDGE),
                        TRUE, TRUE, 5);
 
     gtk_box_pack_start (GTK_BOX (hbox), 
-          create_bbox (FALSE, "Start", 30, GTK_BUTTONBOX_START),
+                        create_bbox (FALSE, "Start", 30, GTK_BUTTONBOX_START),
                        TRUE, TRUE, 5);
 
     gtk_box_pack_start (GTK_BOX (hbox), 
-          create_bbox (FALSE, "End", 30, GTK_BUTTONBOX_END),
+                        create_bbox (FALSE, "End", 30, GTK_BUTTONBOX_END),
                        TRUE, TRUE, 5);
   }
 
diff --git a/demos/gtk-demo/drawingarea.c b/demos/gtk-demo/drawingarea.c
new file mode 100644 (file)
index 0000000..101b159
--- /dev/null
@@ -0,0 +1,322 @@
+/* Drawing Area
+ *
+ * GtkDrawingArea is a blank area where you can draw custom displays
+ * of various kinds.
+ *
+ * This demo has two drawing areas. The checkerboard area shows
+ * how you can just draw something; all you have to do is write
+ * a signal handler for expose_event, as shown here.
+ *
+ * The "scribble" area is a bit more advanced, and shows how to handle
+ * events such as button presses and mouse motion. Click the mouse
+ * and drag in the scribble area to draw squiggles. Resize the window
+ * to clear the area.
+ */
+
+#include <gtk/gtk.h>
+
+static GtkWidget *window = NULL;
+/* Pixmap for scribble area, to store current scribbles */
+static GdkPixmap *pixmap = NULL;
+
+/* Create a new pixmap of the appropriate size to store our scribbles */
+static gboolean
+scribble_configure_event (GtkWidget         *widget,
+                          GdkEventConfigure *event,
+                          gpointer           data)
+{
+  if (pixmap)
+    g_object_unref (G_OBJECT (pixmap));
+
+  pixmap = gdk_pixmap_new (widget->window,
+                           widget->allocation.width,
+                           widget->allocation.height,
+                           -1);
+
+  /* Initialize the pixmap to white */
+  gdk_draw_rectangle (pixmap,
+                     widget->style->white_gc,
+                     TRUE,
+                     0, 0,
+                     widget->allocation.width,
+                     widget->allocation.height);
+
+  /* We've handled the configure event, no need for further processing. */
+  return TRUE;
+}
+
+/* Redraw the screen from the pixmap */
+static gboolean
+scribble_expose_event (GtkWidget      *widget,
+                       GdkEventExpose *event,
+                       gpointer        data)
+{
+  /* We use the "foreground GC" for the widget since it already exists,
+   * but honestly any GC would work. The only thing to worry about
+   * is whether the GC has an inappropriate clip region set.
+   */
+  
+  gdk_draw_drawable (widget->window,
+                     widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
+                     pixmap,
+                     /* Only copy the area that was exposed. */
+                     event->area.x, event->area.y,
+                     event->area.x, event->area.y,
+                     event->area.width, event->area.height);
+  
+  return FALSE;
+}
+
+/* Draw a rectangle on the screen */
+static void
+draw_brush (GtkWidget *widget,
+            gdouble    x,
+            gdouble    y)
+{
+  GdkRectangle update_rect;
+
+  update_rect.x = x - 3;
+  update_rect.y = y - 3;
+  update_rect.width = 6;
+  update_rect.height = 6;
+
+  /* Paint to the pixmap, where we store our state */
+  gdk_draw_rectangle (pixmap,
+                     widget->style->black_gc,
+                     TRUE,
+                     update_rect.x, update_rect.y,
+                     update_rect.width, update_rect.height);
+
+  /* Now invalidate the affected region of the drawing area. */
+  gdk_window_invalidate_rect (widget->window,
+                              &update_rect,
+                              FALSE);
+}
+
+static gboolean
+scribble_button_press_event (GtkWidget      *widget,
+                             GdkEventButton *event,
+                             gpointer        data)
+{
+  if (pixmap == NULL)
+    return FALSE; /* paranoia check, in case we haven't gotten a configure event */
+  
+  if (event->button == 1)
+    draw_brush (widget, event->x, event->y);
+
+  /* We've handled the event, stop processing */
+  return TRUE;
+}
+
+static gboolean
+scribble_motion_notify_event (GtkWidget      *widget,
+                              GdkEventMotion *event,
+                              gpointer        data)
+{
+  int x, y;
+  GdkModifierType state;
+
+  if (pixmap == NULL)
+    return FALSE; /* paranoia check, in case we haven't gotten a configure event */
+
+  /* This call is very important; it requests the next motion event.
+   * If you don't call gdk_window_get_pointer() you'll only get
+   * a single motion event. The reason is that we specified
+   * GDK_POINTER_MOTION_HINT_MASK to gtk_widget_set_events().
+   * If we hadn't specified that, we could just use event->x, event->y
+   * as the pointer location. But we'd also get deluged in events.
+   * By requesting the next event as we handle the current one,
+   * we avoid getting a huge number of events faster than we
+   * can cope.
+   */
+  
+  gdk_window_get_pointer (event->window, &x, &y, &state);
+    
+  if (state & GDK_BUTTON1_MASK)
+    draw_brush (widget, x, y);
+
+  /* We've handled it, stop processing */
+  return TRUE;
+}
+
+
+static gboolean
+checkerboard_expose (GtkWidget      *da,
+                     GdkEventExpose *event,
+                     gpointer        data)
+{
+  gint i, j, xcount, ycount;
+  GdkGC *gc1, *gc2;
+  GdkColor color;
+  
+#define CHECK_SIZE 10
+#define SPACING 2
+  
+  /* At the start of an expose handler, a clip region of event->area
+   * is set on the window, and event->area has been cleared to the
+   * widget's background color. The docs for
+   * gdk_window_begin_paint_region() give more details on how this
+   * works.
+   */
+
+  /* It would be a bit more efficient to keep these
+   * GC's around instead of recreating on each expose, but
+   * this is the lazy/slow way.
+   */
+  gc1 = gdk_gc_new (da->window);
+  color.red = 30000;
+  color.green = 0;
+  color.blue = 30000;
+  gdk_gc_set_rgb_fg_color (gc1, &color);
+
+  gc2 = gdk_gc_new (da->window);
+  color.red = 65535;
+  color.green = 65535;
+  color.blue = 65535;
+  gdk_gc_set_rgb_fg_color (gc2, &color);
+  
+  xcount = 0;
+  i = SPACING;
+  while (i < da->allocation.width)
+    {
+      j = SPACING;
+      ycount = xcount % 2; /* start with even/odd depending on row */
+      while (j < da->allocation.height)
+        {
+          GdkGC *gc;
+          
+          if (ycount % 2)
+            gc = gc1;
+          else
+            gc = gc2;
+
+          /* If we're outside event->area, this will do nothing.
+           * It might be mildly more efficient if we handled
+           * the clipping ourselves, but again we're feeling lazy.
+           */
+          gdk_draw_rectangle (da->window,
+                              gc,
+                              TRUE,
+                              i, j,
+                              CHECK_SIZE,
+                              CHECK_SIZE);
+
+          j += CHECK_SIZE + SPACING;
+          ++ycount;
+        }
+
+      i += CHECK_SIZE + SPACING;
+      ++xcount;
+    }
+  
+  g_object_unref (G_OBJECT (gc1));
+  g_object_unref (G_OBJECT (gc2));
+  
+  /* return TRUE because we've handled this event, so no
+   * further processing is required.
+   */
+  return TRUE;
+}
+
+GtkWidget *
+do_drawingarea (void)
+{
+  GtkWidget *frame;
+  GtkWidget *vbox;
+  GtkWidget *da;
+  GtkWidget *label;
+  
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+      gtk_window_set_title (GTK_WINDOW (window), "Drawing Area");
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy", GTK_SIGNAL_FUNC (gtk_widget_destroyed), &window);
+
+      gtk_container_set_border_width (GTK_CONTAINER (window), 8);
+
+      vbox = gtk_vbox_new (FALSE, 8);
+      gtk_container_set_border_width (GTK_CONTAINER (vbox), 8);
+      gtk_container_add (GTK_CONTAINER (window), vbox);
+
+      /*
+       * Create the checkerboard area
+       */
+      
+      label = gtk_label_new (NULL);
+      gtk_label_set_markup (GTK_LABEL (label),
+                            "<u>Checkerboard pattern</u>");
+      gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+      
+      frame = gtk_frame_new (NULL);
+      gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
+      gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0);
+      
+      da = gtk_drawing_area_new ();
+      /* set a minimum size */
+      gtk_widget_set_usize (da, 100, 100);
+
+      gtk_container_add (GTK_CONTAINER (frame), da);
+
+      gtk_signal_connect (GTK_OBJECT (da),
+                          "expose_event",
+                          GTK_SIGNAL_FUNC (checkerboard_expose),
+                          NULL);
+
+      /*
+       * Create the scribble area
+       */
+      
+      label = gtk_label_new (NULL);
+      gtk_label_set_markup (GTK_LABEL (label),
+                            "<u>Scribble area</u>");
+      gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+      
+      frame = gtk_frame_new (NULL);
+      gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
+      gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0);
+      
+      da = gtk_drawing_area_new ();
+      /* set a minimum size */
+      gtk_widget_set_usize (da, 100, 100);
+
+      gtk_container_add (GTK_CONTAINER (frame), da);
+
+      /* Signals used to handle backing pixmap */
+      
+      gtk_signal_connect (GTK_OBJECT (da), "expose_event",
+                          GTK_SIGNAL_FUNC (scribble_expose_event), NULL);
+      gtk_signal_connect (GTK_OBJECT (da),"configure_event",
+                          GTK_SIGNAL_FUNC (scribble_configure_event), NULL);
+      
+      /* Event signals */
+      
+      gtk_signal_connect (GTK_OBJECT (da), "motion_notify_event",
+                          GTK_SIGNAL_FUNC (scribble_motion_notify_event), NULL);
+      gtk_signal_connect (GTK_OBJECT (da), "button_press_event",
+                          GTK_SIGNAL_FUNC (scribble_button_press_event), NULL);
+
+
+      /* Ask to receive events the drawing area doesn't normally
+       * subscribe to
+       */
+      gtk_widget_set_events (da, gtk_widget_get_events (da)
+                             | GDK_LEAVE_NOTIFY_MASK
+                             | GDK_BUTTON_PRESS_MASK
+                             | GDK_POINTER_MOTION_MASK
+                             | GDK_POINTER_MOTION_HINT_MASK);
+
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    {
+      gtk_widget_show_all (window);
+    }
+  else
+    {
+      gtk_widget_destroy (window);
+      window = NULL;
+    }
+
+  return window;
+}
diff --git a/demos/gtk-demo/gnome-applets.png b/demos/gtk-demo/gnome-applets.png
new file mode 100644 (file)
index 0000000..8d3549e
Binary files /dev/null and b/demos/gtk-demo/gnome-applets.png differ
diff --git a/demos/gtk-demo/gnome-calendar.png b/demos/gtk-demo/gnome-calendar.png
new file mode 100644 (file)
index 0000000..889f329
Binary files /dev/null and b/demos/gtk-demo/gnome-calendar.png differ
diff --git a/demos/gtk-demo/gnome-foot.png b/demos/gtk-demo/gnome-foot.png
new file mode 100644 (file)
index 0000000..0476658
Binary files /dev/null and b/demos/gtk-demo/gnome-foot.png differ
diff --git a/demos/gtk-demo/gnome-gimp.png b/demos/gtk-demo/gnome-gimp.png
new file mode 100644 (file)
index 0000000..f6bbc6d
Binary files /dev/null and b/demos/gtk-demo/gnome-gimp.png differ
diff --git a/demos/gtk-demo/gnome-gmush.png b/demos/gtk-demo/gnome-gmush.png
new file mode 100644 (file)
index 0000000..0a4b0d0
Binary files /dev/null and b/demos/gtk-demo/gnome-gmush.png differ
diff --git a/demos/gtk-demo/gnome-gsame.png b/demos/gtk-demo/gnome-gsame.png
new file mode 100644 (file)
index 0000000..01c0611
Binary files /dev/null and b/demos/gtk-demo/gnome-gsame.png differ
diff --git a/demos/gtk-demo/gnu-keys.png b/demos/gtk-demo/gnu-keys.png
new file mode 100644 (file)
index 0000000..58a3377
Binary files /dev/null and b/demos/gtk-demo/gnu-keys.png differ
diff --git a/demos/gtk-demo/gtk-logo-rgb.gif b/demos/gtk-demo/gtk-logo-rgb.gif
new file mode 100644 (file)
index 0000000..f6e934d
Binary files /dev/null and b/demos/gtk-demo/gtk-logo-rgb.gif differ
diff --git a/demos/gtk-demo/images.c b/demos/gtk-demo/images.c
new file mode 100644 (file)
index 0000000..756046e
--- /dev/null
@@ -0,0 +1,396 @@
+/* Images
+ *
+ * GtkImage is used to display an image; the image can be in a number of formats.
+ * Typically, you load an image into a GdkPixbuf, then display the pixbuf.
+ *
+ * This demo code shows some of the more obscure cases, in the simple
+ * case a call to gtk_image_new_from_file() is all you need.
+ *
+ * If you want to put image data in your program as a C variable,
+ * use the make-inline-pixbuf program that comes with GTK+.
+ */
+
+#include <gtk/gtk.h>
+#include <stdio.h>
+#include <errno.h>
+
+static GtkWidget *window = NULL;
+static GdkPixbufLoader *pixbuf_loader = NULL;
+static guint load_timeout = 0;
+static FILE* image_stream = NULL;
+
+static void
+progressive_prepared_callback (GdkPixbufLoader* loader, gpointer data)
+{
+  GdkPixbuf* pixbuf;
+  GtkWidget* image;
+
+  image = GTK_WIDGET (data);
+  
+  pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
+
+  /* Avoid displaying random memory contents, since the pixbuf
+   * isn't filled in yet.
+   */
+  gdk_pixbuf_fill (pixbuf, 0xaaaaaaff);
+  
+  gtk_image_set_from_pixbuf (GTK_IMAGE (image), pixbuf);
+}
+
+static void
+progressive_updated_callback (GdkPixbufLoader* loader,
+                              guint x, guint y, guint width, guint height,
+                              gpointer data)
+{
+  GtkWidget* image;
+  
+  image = GTK_WIDGET (data);
+
+  /* We know the pixbuf inside the image has changed, but the image
+   * itself doesn't know this; so queue a redraw.  If we wanted to be
+   * really efficient, we could use a drawing area or something
+   * instead of a GtkImage, so we could control the exact position of
+   * the pixbuf on the display, then we could queue a draw for only
+   * the updated area of the image.
+   */
+  
+  gtk_widget_queue_draw (image);
+}
+
+static gint
+progressive_timeout (gpointer data)
+{
+  GtkWidget *image;
+
+  image = GTK_WIDGET (data);
+  
+  /* This shows off fully-paranoid error handling, so looks scary.
+   * You could factor out the error handling code into a nice separate
+   * function to make things nicer.
+   */
+  
+  if (image_stream)
+    {
+      size_t bytes_read;
+      guchar buf[256];
+      GError *error = NULL;
+      
+      bytes_read = fread (buf, 1, 256, image_stream);
+
+      if (ferror (image_stream))
+        {
+          GtkWidget *dialog;
+          
+          dialog = gtk_message_dialog_new (GTK_WINDOW (window),
+                                           GTK_DIALOG_DESTROY_WITH_PARENT,
+                                           GTK_MESSAGE_ERROR,
+                                           GTK_BUTTONS_CLOSE,
+                                           "Failure reading image file 'gtk-logo-rgb.gif': %s",
+                                           g_strerror (errno));
+
+          gtk_signal_connect (GTK_OBJECT (dialog),
+                              "response",
+                              GTK_SIGNAL_FUNC (gtk_widget_destroy),
+                              NULL);
+
+          fclose (image_stream);
+          image_stream = NULL;
+
+          gtk_widget_show (dialog);
+          
+          load_timeout = 0;
+
+          return FALSE; /* uninstall the timeout */
+        }
+
+      if (!gdk_pixbuf_loader_write (pixbuf_loader,
+                                    buf, bytes_read,
+                                    &error))
+        {
+          GtkWidget *dialog;
+          
+          dialog = gtk_message_dialog_new (GTK_WINDOW (window),
+                                           GTK_DIALOG_DESTROY_WITH_PARENT,
+                                           GTK_MESSAGE_ERROR,
+                                           GTK_BUTTONS_CLOSE,
+                                           "Failed to load image: %s",
+                                           error->message);
+
+          g_error_free (error);
+          
+          gtk_signal_connect (GTK_OBJECT (dialog),
+                              "response",
+                              GTK_SIGNAL_FUNC (gtk_widget_destroy),
+                              NULL);
+
+          fclose (image_stream);
+          image_stream = NULL;
+          
+          gtk_widget_show (dialog);
+
+          load_timeout = 0;
+
+          return FALSE; /* uninstall the timeout */
+        }
+
+      if (feof (image_stream))
+        {
+          fclose (image_stream);
+          image_stream = NULL;
+
+          /* Errors can happen on close, e.g. if the image
+           * file was truncated we'll know on close that
+           * it was incomplete.
+           */
+          error = NULL;
+          if (!gdk_pixbuf_loader_close (pixbuf_loader,
+                                        &error))
+            {
+              GtkWidget *dialog;
+              
+              dialog = gtk_message_dialog_new (GTK_WINDOW (window),
+                                               GTK_DIALOG_DESTROY_WITH_PARENT,
+                                               GTK_MESSAGE_ERROR,
+                                               GTK_BUTTONS_CLOSE,
+                                               "Failed to load image: %s",
+                                               error->message);
+              
+              g_error_free (error);
+              
+              gtk_signal_connect (GTK_OBJECT (dialog),
+                                  "response",
+                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
+                                  NULL);
+              
+              gtk_widget_show (dialog);
+
+              g_object_unref (G_OBJECT (pixbuf_loader));
+              pixbuf_loader = NULL;
+              
+              load_timeout = 0;
+              
+              return FALSE; /* uninstall the timeout */
+            }
+          
+          g_object_unref (G_OBJECT (pixbuf_loader));
+          pixbuf_loader = NULL;
+        }
+    }
+  else
+    {
+      const gchar *filename;
+
+      if (g_file_test ("./gtk-logo-rgb.gif", G_FILE_TEST_EXISTS))
+        filename = "./gtk-logo-rgb.gif";
+      else
+        filename = DEMOCODEDIR"/gtk-log-rgb.gif";
+      
+      image_stream = fopen (filename, "r");
+
+      if (image_stream == NULL)
+        {
+          GtkWidget *dialog;
+          
+          dialog = gtk_message_dialog_new (GTK_WINDOW (window),
+                                           GTK_DIALOG_DESTROY_WITH_PARENT,
+                                           GTK_MESSAGE_ERROR,
+                                           GTK_BUTTONS_CLOSE,
+                                           "Unable to open image file 'gtk-logo-rgb.gif': %s",
+                                           g_strerror (errno));
+
+          gtk_signal_connect (GTK_OBJECT (dialog),
+                              "response",
+                              GTK_SIGNAL_FUNC (gtk_widget_destroy),
+                              NULL);
+          
+          gtk_widget_show (dialog);
+
+          load_timeout = 0;
+
+          return FALSE; /* uninstall the timeout */
+        }
+
+      if (pixbuf_loader)
+        {
+          gdk_pixbuf_loader_close (pixbuf_loader, NULL);
+          g_object_unref (G_OBJECT (pixbuf_loader));
+          pixbuf_loader = NULL;
+        }
+      
+      pixbuf_loader = gdk_pixbuf_loader_new ();
+      
+      g_signal_connect_data (G_OBJECT (pixbuf_loader),
+                             "area_prepared",
+                             G_CALLBACK (progressive_prepared_callback),
+                             image,
+                             NULL, FALSE, FALSE);
+      
+      g_signal_connect_data (G_OBJECT (pixbuf_loader),
+                             "area_updated",
+                             G_CALLBACK (progressive_updated_callback),
+                             image,
+                             NULL, FALSE, FALSE);
+    }
+
+  /* leave timeout installed */
+  return TRUE;
+}
+
+static void
+start_progressive_loading (GtkWidget *image)
+{
+  /* This is obviously totally contrived (we slow down loading
+   * on purpose to show how incremental loading works).
+   * The real purpose of incremental loading is the case where
+   * you are reading data from a slow source such as the network.
+   * The timeout simply simulates a slow data source by inserting
+   * pauses in the reading process.
+   */
+  load_timeout = g_timeout_add (300,
+                                progressive_timeout,
+                                image);
+}
+
+static void
+cleanup_callback (GtkObject *object,
+                  gpointer data)
+{
+  if (load_timeout)
+    {
+      g_source_remove (load_timeout);
+      load_timeout = 0;
+    }
+  
+  if (pixbuf_loader)
+    {
+      gdk_pixbuf_loader_close (pixbuf_loader, NULL);
+      g_object_unref (G_OBJECT (pixbuf_loader));
+      pixbuf_loader = NULL;
+    }
+
+  if (image_stream)
+    fclose (image_stream);
+  image_stream = NULL;
+}
+
+GtkWidget *
+do_images (void)
+{
+  GtkWidget *frame;
+  GtkWidget *vbox;
+  GtkWidget *image;
+  GtkWidget *label;
+  GtkWidget *align;
+  
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+      gtk_window_set_title (GTK_WINDOW (window), "Images");
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy", GTK_SIGNAL_FUNC (gtk_widget_destroyed), &window);
+      gtk_signal_connect (GTK_OBJECT (window), "destroy", GTK_SIGNAL_FUNC (cleanup_callback), NULL);
+
+      gtk_container_set_border_width (GTK_CONTAINER (window), 8);
+
+      vbox = gtk_vbox_new (FALSE, 8);
+      gtk_container_set_border_width (GTK_CONTAINER (vbox), 8);
+      gtk_container_add (GTK_CONTAINER (window), vbox);
+
+      label = gtk_label_new (NULL);
+      gtk_label_set_markup (GTK_LABEL (label),
+                            "<u>Image loaded from a file</u>");
+      gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+      
+      frame = gtk_frame_new (NULL);
+      gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
+      /* The alignment keeps the frame from growing when users resize
+       * the window
+       */
+      align = gtk_alignment_new (0.5, 0.5, 0, 0);
+      gtk_container_add (GTK_CONTAINER (align), frame);
+      gtk_box_pack_start (GTK_BOX (vbox), align, FALSE, FALSE, 0);
+
+      /* We look for the image in the current directory first,
+       * so you can run gtk-demo without installing GTK
+       */
+      if (g_file_test ("./gtk-logo-rgb.gif", G_FILE_TEST_EXISTS))
+        {
+          /* This code shows off error handling. You can just use
+           * gtk_image_new_from_file() instead if you don't want to report
+           * errors to the user. If the file doesn't load when using
+           * gtk_image_new_from_file(), a "missing image" icon will
+           * be displayed instead.
+           */
+          GdkPixbuf *pixbuf;
+          GError *error = NULL;
+          
+          pixbuf = gdk_pixbuf_new_from_file ("./gtk-logo-rgb.gif",
+                                             &error);
+          if (error)
+            {
+              GtkWidget *dialog;
+
+              dialog = gtk_message_dialog_new (GTK_WINDOW (window),
+                                               GTK_DIALOG_DESTROY_WITH_PARENT,
+                                               GTK_MESSAGE_ERROR,
+                                               GTK_BUTTONS_CLOSE,
+                                               "Unable to open image file 'gtk-logo-rgb.gif': %s",
+                                               error->message);
+              g_error_free (error);
+              
+              gtk_signal_connect (GTK_OBJECT (dialog),
+                                  "response",
+                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
+                                  NULL);
+              
+              gtk_widget_show (dialog);
+            }
+          
+          image = gtk_image_new_from_pixbuf (pixbuf);
+        }
+      else
+        {
+          /* This is the simpler code, with no error handling.
+           * Here we're loading the installed gtk-logo-rgb.gif instead
+           * of the one in the current directory.
+           */
+          image = gtk_image_new_from_file (DEMOCODEDIR"/gtk-logo-rgb.gif");
+        }
+
+      gtk_container_add (GTK_CONTAINER (frame), image);
+
+      label = gtk_label_new (NULL);
+      gtk_label_set_markup (GTK_LABEL (label),
+                            "<u>Progressive image loading</u>");
+      gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+      
+      frame = gtk_frame_new (NULL);
+      gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
+      /* The alignment keeps the frame from growing when users resize
+       * the window
+       */
+      align = gtk_alignment_new (0.5, 0.5, 0, 0);
+      gtk_container_add (GTK_CONTAINER (align), frame);
+      gtk_box_pack_start (GTK_BOX (vbox), align, FALSE, FALSE, 0);
+
+      /* Create an empty image for now; the progressive loader
+       * will create the pixbuf and fill it in.
+       */
+      image = gtk_image_new_from_pixbuf (NULL);
+      gtk_container_add (GTK_CONTAINER (frame), image);
+
+      start_progressive_loading (image);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    {
+      gtk_widget_show_all (window);
+    }
+  else
+    {
+      gtk_widget_destroy (window);
+      window = NULL;
+    }
+
+  return window;
+}
index 0dfb4b1e26c15e911d1ae5d26e120ea9ad8a14e3..fabf898d44dc750e82b622be11a85c435bcf6d83 100644 (file)
@@ -299,16 +299,18 @@ button_press_event_cb (GtkTreeView    *tree_view,
   return FALSE;
 }
 
-gboolean
+void
 row_activated_cb (GtkTreeView       *tree_view,
-                 GtkTreePath       *path,
-                 GtkTreeViewColumn *column,
-                 GtkTreeModel      *model)
+                  GtkTreePath       *path,
+                 GtkTreeViewColumn *column)
 {
   GtkTreeIter iter;
   gboolean italic;
   GDoDemoFunc func;
   GtkWidget *window;
+  GtkTreeModel *model;
+
+  model = gtk_tree_view_get_model (tree_view);
   
   gtk_tree_model_get_iter (model, &iter, path);
   gtk_tree_model_get (GTK_TREE_MODEL (model),
@@ -321,6 +323,7 @@ row_activated_cb (GtkTreeView       *tree_view,
                      ITALIC_COLUMN, !italic,
                      -1);
   window = (func) ();
+
   if (window != NULL)
     {
       CallbackData *cbdata;
@@ -334,10 +337,6 @@ row_activated_cb (GtkTreeView       *tree_view,
                          window_closed_cb,
                          cbdata);
     }
-  else
-    {
-      gtk_tree_path_free (path);
-    }
 }
 
 static void
@@ -385,9 +384,20 @@ create_text (GtkTextBuffer **buffer,
       font_desc = pango_font_description_from_string ("Courier 10");
       gtk_widget_modify_font (text_view, font_desc);
       pango_font_description_free (font_desc);
+
+      gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (text_view),
+                                   GTK_WRAP_NONE);
+    }
+  else
+    {
+      /* Make it a bit nicer for text. */
+      gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (text_view),
+                                   GTK_WRAP_WORD);
+      gtk_text_view_set_pixels_above_lines (GTK_TEXT_VIEW (text_view),
+                                            2);
+      gtk_text_view_set_pixels_below_lines (GTK_TEXT_VIEW (text_view),
+                                            2);
     }
-  
-  gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (text_view), !is_source);
   
   return scrolled_window;
 }
@@ -458,6 +468,7 @@ main (int argc, char **argv)
   gtk_init (&argc, &argv);
   
   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_title (GTK_WINDOW (window), "GTK+ Code Demos");
   gtk_signal_connect (GTK_OBJECT (window), "destroy",
                      GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
 
index ac8a7e2c5350a1997b72adfcbec90a2e18e17c0e..4788edd861e703b5a4a0924ad4c034cb7f6a0058 100644 (file)
@@ -1,10 +1,31 @@
 /* Menus
  *
- * GTK+ includes a number of widgets for menus of actions.
- * GtkMenu is a drop-down menu, GtkMenuBar a horizontal menu bar.
- * Each of these widgets can hold various types of menuitem.
- * As well as the base type, GtkMenuItem, there are GtkCheckMenuItem,
- * GtkRadioMenuItem and GtkTearoffMenuItem.
+ * There are several widgets involved in displaying menus. The
+ * GtkMenuBar widget is a horizontal menu bar, which normally appears
+ * at the top of an application. The GtkMenu widget is the actual menu
+ * that pops up. Both GtkMenuBar and GtkMenu are subclasses of
+ * GtkMenuShell; a GtkMenuShell contains menu items
+ * (GtkMenuItem). Each menu item contains text and/or images and can
+ * be selected by the user.
+ *
+ * There are several kinds of menu item, including plain GtkMenuItem,
+ * GtkCheckMenuItem which can be checked/unchecked, GtkRadioMenuItem
+ * which is a check menu item that's in a mutually exclusive group,
+ * GtkSeparatorMenuItem which is a separator bar, GtkTearoffMenuItem
+ * which allows a GtkMenu to be torn off, and GtkImageMenuItem which
+ * can place a GtkImage or other widget next to the menu text.
+ *
+ * A GtkMenuItem can have a submenu, which is simply a GtkMenu to pop
+ * up when the menu item is selected. Typically, all menu items in a menu bar
+ * have submenus.
+ *
+ * The GtkOptionMenu widget is a button that pops up a GtkMenu when clicked.
+ * It's used inside dialogs and such.
+ *
+ * GtkItemFactory provides a higher-level interface for creating menu bars
+ * and menus; while you can construct menus manually, most people don't
+ * do that. There's a separate demo for GtkItemFactory.
+ * 
  */
 
 #include <stdio.h>
@@ -39,8 +60,7 @@ create_menu (gint depth, gboolean tearoff)
       sprintf (buf, "item %2d - %d", depth, j);
       menuitem = gtk_radio_menu_item_new_with_label (group, buf);
       group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem));
-      if (depth % 2)
-       gtk_check_menu_item_set_show_toggle (GTK_CHECK_MENU_ITEM (menuitem), TRUE);
+
       gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
       gtk_widget_show (menuitem);
       if (i == 3)
diff --git a/demos/gtk-demo/pixbufs.c b/demos/gtk-demo/pixbufs.c
new file mode 100644 (file)
index 0000000..6c06709
--- /dev/null
@@ -0,0 +1,277 @@
+/* Pixbufs
+ *
+ * A GdkPixbuf represents an image, normally in RGB or RGBA format.
+ * Pixbufs are normally used to load files from disk and perform
+ * image scaling.
+ *
+ * This demo is not all that educational, but looks cool. It was written
+ * by Extreme Pixbuf Hacker Federico Mena Quintero. It also shows
+ * off how to use GtkDrawingArea to do a simple animation.
+ *
+ * Look at the Image demo for additional pixbuf usage examples.
+ * 
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <gtk/gtk.h>
+#include <math.h>
+
+\f
+
+#define FRAME_DELAY 50
+
+#define RELATIVE_BACKGROUND_NAME "background.jpg"
+#define INSTALLED_BACKGROUND_NAME DEMOCODEDIR"/background.jpg"
+
+static const char *relative_image_names[] = {
+  "apple-red.png",
+  "gnome-applets.png",
+  "gnome-calendar.png",
+  "gnome-foot.png",
+  "gnome-gmush.png",
+  "gnome-gimp.png",
+  "gnome-gsame.png",
+  "gnu-keys.png"
+};
+
+static const char *installed_image_names[] = {
+  DEMOCODEDIR"/apple-red.png",
+  DEMOCODEDIR"/gnome-applets.png",
+  DEMOCODEDIR"/gnome-calendar.png",
+  DEMOCODEDIR"/gnome-foot.png",
+  DEMOCODEDIR"/gnome-gmush.png",
+  DEMOCODEDIR"/gnome-gimp.png",
+  DEMOCODEDIR"/gnome-gsame.png",
+  DEMOCODEDIR"/gnu-keys.png"
+};
+
+#define N_IMAGES G_N_ELEMENTS (relative_image_names)
+
+/* demo window */
+static GtkWindow *window = NULL;
+
+/* Current frame */
+static GdkPixbuf *frame;
+
+/* Background image */
+static GdkPixbuf *background;
+static int back_width, back_height;
+
+/* Images */
+static GdkPixbuf *images[N_IMAGES];
+
+/* Widgets */
+static GtkWidget *da;
+
+\f
+
+/* Loads the images for the demo and returns whether the operation succeeded */
+static gboolean
+load_pixbufs (GError **error)
+{
+  int i;
+  const char **image_names;
+
+  if (background)
+    return TRUE; /* already loaded earlier */
+  
+  background = gdk_pixbuf_new_from_file (RELATIVE_BACKGROUND_NAME, NULL);
+
+  if (!background)
+    background = gdk_pixbuf_new_from_file (INSTALLED_BACKGROUND_NAME, error);
+
+  if (!background)
+    return FALSE; /* note that "error" was filled in and returned */
+  
+  back_width = gdk_pixbuf_get_width (background);
+  back_height = gdk_pixbuf_get_height (background);
+
+  if (g_file_test (relative_image_names[0], G_FILE_TEST_EXISTS))
+    image_names = relative_image_names;
+  else
+    image_names = installed_image_names;
+  
+  for (i = 0; i < N_IMAGES; i++)
+    {
+      images[i] = gdk_pixbuf_new_from_file (image_names[i], error);
+      if (!images[i])
+        return FALSE; /* Note that "error" was filled with a GError */
+    }
+
+  return TRUE;
+}
+
+/* Expose callback for the drawing area */
+static gint
+expose_cb (GtkWidget *widget, GdkEventExpose *event, gpointer data)
+{
+  guchar *pixels;
+  int rowstride;
+
+  rowstride = gdk_pixbuf_get_rowstride (frame);
+
+  pixels = gdk_pixbuf_get_pixels (frame) + rowstride * event->area.y + event->area.x * 3;
+                 
+  gdk_draw_rgb_image_dithalign (widget->window,
+                                widget->style->black_gc,
+                                event->area.x, event->area.y,
+                                event->area.width, event->area.height,
+                                GDK_RGB_DITHER_NORMAL,
+                                pixels, rowstride,
+                                event->area.x, event->area.y);
+
+  return TRUE;
+}
+
+#define CYCLE_LEN 60
+
+static int frame_num;
+
+/* Timeout handler to regenerate the frame */
+static gint
+timeout (gpointer data)
+{
+  double f;
+  int i;
+  double xmid, ymid;
+  double radius;
+
+  gdk_pixbuf_copy_area (background, 0, 0, back_width, back_height,
+                        frame, 0, 0);
+
+  f = (double) (frame_num % CYCLE_LEN) / CYCLE_LEN;
+
+  xmid = back_width / 2.0;
+  ymid = back_height / 2.0;
+
+  radius = MIN (xmid, ymid) / 2.0;
+
+  for (i = 0; i < N_IMAGES; i++)
+    {
+      double ang;
+      int xpos, ypos;
+      int iw, ih;
+      double r;
+      GdkRectangle r1, r2, dest;
+      double k;
+
+      ang = 2.0 * M_PI * (double) i / N_IMAGES - f * 2.0 * M_PI;
+
+      iw = gdk_pixbuf_get_width (images[i]);
+      ih = gdk_pixbuf_get_height (images[i]);
+
+      r = radius + (radius / 3.0) * sin (f * 2.0 * M_PI);
+
+      xpos = floor (xmid + r * cos (ang) - iw / 2.0 + 0.5);
+      ypos = floor (ymid + r * sin (ang) - ih / 2.0 + 0.5);
+
+      k = (i & 1) ? sin (f * 2.0 * M_PI) : cos (f * 2.0 * M_PI);
+      k = 2.0 * k * k;
+      k = MAX (0.25, k);
+
+      r1.x = xpos;
+      r1.y = ypos;
+      r1.width = iw * k;
+      r1.height = ih * k;
+
+      r2.x = 0;
+      r2.y = 0;
+      r2.width = back_width;
+      r2.height = back_height;
+
+      if (gdk_rectangle_intersect (&r1, &r2, &dest))
+        gdk_pixbuf_composite (images[i],
+                              frame,
+                              dest.x, dest.y,
+                              dest.width, dest.height,
+                              xpos, ypos,
+                              k, k,
+                              GDK_INTERP_NEAREST,
+                              ((i & 1)
+                               ? MAX (127, fabs (255 * sin (f * 2.0 * M_PI)))
+                               : MAX (127, fabs (255 * cos (f * 2.0 * M_PI)))));
+    }
+
+  gtk_widget_queue_draw (da);
+
+  frame_num++;
+  return TRUE;
+}
+
+static guint timeout_id;
+
+static void
+cleanup_callback (GtkObject *object,
+                  gpointer data)
+{
+  g_source_remove (timeout_id);
+  timeout_id = 0;
+}
+
+GtkWidget *
+do_pixbufs (void)
+{
+  if (!window)
+    {
+      GError *error;
+
+      
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+      gtk_window_set_title (GTK_WINDOW (window), "Pixbufs");
+      gtk_window_set_resizeable (GTK_WINDOW (window), FALSE);
+      
+      gtk_signal_connect (GTK_OBJECT (window), "destroy", GTK_SIGNAL_FUNC (gtk_widget_destroyed), &window);
+      gtk_signal_connect (GTK_OBJECT (window), "destroy", GTK_SIGNAL_FUNC (cleanup_callback), NULL);
+
+      
+      error = NULL;
+      if (!load_pixbufs (&error))
+        {
+          GtkWidget *dialog;
+          
+          dialog = gtk_message_dialog_new (GTK_WINDOW (window),
+                                           GTK_DIALOG_DESTROY_WITH_PARENT,
+                                           GTK_MESSAGE_ERROR,
+                                           GTK_BUTTONS_CLOSE,
+                                           "Failed to load an image: %s",
+                                           error->message);
+          
+          g_error_free (error);
+          
+          gtk_signal_connect (GTK_OBJECT (dialog),
+                              "response",
+                              GTK_SIGNAL_FUNC (gtk_widget_destroy),
+                              NULL);
+          
+          gtk_widget_show (dialog);
+        }
+      else
+        {
+          gtk_widget_set_usize (window, back_width, back_height);
+          
+          frame = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, back_width, back_height);
+          
+          da = gtk_drawing_area_new ();
+          
+          gtk_signal_connect (GTK_OBJECT (da), "expose_event",
+                              GTK_SIGNAL_FUNC (expose_cb), NULL);
+          
+          gtk_container_add (GTK_CONTAINER (window), da);
+          
+          timeout_id = gtk_timeout_add (FRAME_DELAY, timeout, NULL);
+        }
+    }
+  
+  if (!GTK_WIDGET_VISIBLE (window))
+    {
+      gtk_widget_show_all (window);
+    }
+  else
+    {
+      gtk_widget_destroy (window);
+      window = NULL;
+    }
+
+  return window;
+}
index 0ee8aca460a041d5b7e2a22f716a1db8e348c454..641bdf3468b6fc7d39236d8b8b08a83758e1d171 100644 (file)
@@ -49,13 +49,13 @@ static GdkPixbuf *frame;
 
 /* Background image */
 static GdkPixbuf *background;
-int back_width, back_height;
+static int back_width, back_height;
 
 /* Images */
 static GdkPixbuf *images[N_IMAGES];
 
 /* Widgets */
-GtkWidget *da;
+static GtkWidget *da;
 
 \f
 
index 84d2e992e155975167b194892269ea707e3dae0f..c3ee353dcb36884b1456f43ba1648303803c743f 100644 (file)
@@ -723,18 +723,6 @@ produce superscript and subscript.
 </para>
 
 
-<!-- ##### ARG GtkTextView:justify ##### -->
-<para>
-
-</para>
-
-
-<!-- ##### ARG GtkTextView:wrap-mode ##### -->
-<para>
-
-</para>
-
-
 <!-- ##### SIGNAL GtkWidget::activate-mnemonic ##### -->
 <para>
 
index 178b40392298c4059e35c7c6e505cd0fa52ed528..4c81682d1736c779823c68b1ab5f88dd380720a9 100644 (file)
@@ -496,6 +496,7 @@ This can later be composited together with other
 #GtkRcStyle structures to form a #GtkStyle.
 </para>
 
+@parent_instance: 
 @name: 
 @bg_pixmap_name: 
 @font_desc: 
index f168889dc6c614c1da486cac7e3946c775e28301..e4b5b21462202223f13043736f93ceda9c565a26 100644 (file)
@@ -660,6 +660,16 @@ types related to the text widget and how they work together.
 
 </para>
 
+<!-- ##### ARG GtkTextView:wrap-mode ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG GtkTextView:justify ##### -->
+<para>
+
+</para>
+
 <!-- ##### ARG GtkTextView:left-margin ##### -->
 <para>
 
index a3ebb8f284390978516bce4f0e048ce3b9221b85..59eb2f350269e43c79f81956c48e7c2328db7b3b 100644 (file)
@@ -1,3 +1,8 @@
+2001-04-18  Havoc Pennington  <hp@redhat.com>
+
+       * gdk-pixbuf.c (gdk_pixbuf_fill): Function to fill pixbuf with a
+       given color.
+
 Wed Apr  4 01:41:02 2001  Tim Janik  <timj@gtk.org>
 
        * pixops/Makefile.am (noinst_LTLIBRARIES): include $top_srcdir
index 2a65082d939d19a8bf3384e874a834308b04c6ed..12b8e61441623a1dececc2b26f2e8990a496edbf 100644 (file)
@@ -409,6 +409,64 @@ gdk_pixbuf_error_quark (void)
   return q;
 }
 
+/**
+ * gdk_pixbuf_fill:
+ * @pixbuf: a #GdkPixbuf
+ * @pixel: RGBA pixel to clear to (0xffffff00 is opaque white, 0x000000ff transparent black)
+ *
+ * Clears a pixbuf to the given RGBA value, converting the RGBA value into
+ * the pixbuf's pixel format. The alpha will be ignored if the pixbuf
+ * doesn't have an alpha channel.
+ * 
+ **/
+void
+gdk_pixbuf_fill (GdkPixbuf *pixbuf,
+                 guint32    pixel)
+{
+        guchar *pixels;
+        gboolean all_the_same = FALSE;
+        guint r, g, b, a;
+        
+        g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
+
+        pixels = pixbuf->pixels;
+
+        r = (pixel & 0xff000000) >> 24;
+        g = (pixel & 0x00ff0000) >> 16;
+        b = (pixel & 0x0000ff00) >> 8;
+        a = (pixel & 0x000000ff);
+
+        if (r == g && g == b) {
+                if (!pixbuf->has_alpha)
+                        all_the_same = TRUE;
+                else
+                        all_the_same = (r == a);
+        }
+        
+        if (all_the_same) {
+                memset (pixels, r,
+                        pixbuf->rowstride * pixbuf->height);
+        } else {
+                guchar *p;
+                guchar *end;
+
+                /* feel free to optimize this */
+                
+                p = pixels;
+                end = pixels + pixbuf->rowstride * pixbuf->height;
+                end -= (pixbuf->rowstride - pixbuf->width);
+                
+                while (p < end) {
+                        *p++ = r;
+                        *p++ = g;
+                        *p++ = b;
+                        if (pixbuf->has_alpha)
+                                *p++ = a;
+                }
+        }
+}
+
+
 /* Include the marshallers */
 #include <glib-object.h>
 #include "gdk-pixbuf-marshal.c"
index dd40abbe4322cc4394cd5629192767764b41f826..b8b5a03af06c5a044ce879aa43e57a0bf9ef8d96 100644 (file)
@@ -145,6 +145,9 @@ GdkPixbuf *gdk_pixbuf_new_from_inline   (const guchar *inline_pixbuf,
                                          int           length,
                                          GError      **error);
 
+/* Mutations */
+void       gdk_pixbuf_fill              (GdkPixbuf    *pixbuf,
+                                         guint32       pixel);
 
 /* Saving */
 
index 48da4edcd0e060be2592d374a8b688fa83aa0f61..03f5fe0b6882d6d0dab9bd81a4551b35fa1b7b77 100644 (file)
@@ -934,12 +934,8 @@ static void
 gtk_image_reset (GtkImage *image)
 {
   gtk_image_clear (image);
-  
-  GTK_WIDGET (image)->requisition.width = 0;
-  GTK_WIDGET (image)->requisition.height = 0;
-  
-  if (GTK_WIDGET_VISIBLE (image))
-    gtk_widget_queue_resize (GTK_WIDGET (image));
+
+  gtk_image_update_size (image, 0, 0);
 }
 
 static void
@@ -951,6 +947,12 @@ gtk_image_size_request (GtkWidget      *widget,
   
   image = GTK_IMAGE (widget);
 
+  /* We update stock/icon set on every size request, because
+   * the theme could have affected the size; for other kinds of
+   * image, we just update the requisition when the image data
+   * is set.
+   */
+  
   switch (image->storage_type)
     {
     case GTK_IMAGE_STOCK:
@@ -976,9 +978,9 @@ gtk_image_size_request (GtkWidget      *widget,
 
   if (pixbuf)
     {
-      gtk_image_update_size (image,
-                             gdk_pixbuf_get_width (pixbuf),
-                             gdk_pixbuf_get_height (pixbuf));
+      GTK_WIDGET (image)->requisition.width = gdk_pixbuf_get_width (pixbuf) + GTK_MISC (image)->xpad * 2;
+      GTK_WIDGET (image)->requisition.height = gdk_pixbuf_get_height (pixbuf) + GTK_MISC (image)->ypad * 2;
+
       g_object_unref (G_OBJECT (pixbuf));
     }
 
@@ -993,6 +995,9 @@ gtk_image_update_size (GtkImage *image,
 {
   GTK_WIDGET (image)->requisition.width = image_width + GTK_MISC (image)->xpad * 2;
   GTK_WIDGET (image)->requisition.height = image_height + GTK_MISC (image)->ypad * 2;
+
+  if (GTK_WIDGET_VISIBLE (image))
+    gtk_widget_queue_resize (GTK_WIDGET (image));
 }
 
 
index d9de973429f3dd861430a4e67dfecdac34192858..3f9f6bdb209c7c76bfb612e3c6200670fdce1a5c 100644 (file)
@@ -4970,6 +4970,8 @@ gtk_text_view_do_popup (GtkTextView    *text_view,
   GtkWidget *menuitem;
   GtkWidget *submenu;
   gboolean have_selection;
+  gboolean can_insert;
+  GtkTextIter iter;
   
   if (text_view->popup_menu)
     gtk_widget_destroy (text_view->popup_menu);
@@ -4982,13 +4984,20 @@ gtk_text_view_do_popup (GtkTextView    *text_view,
 
   have_selection = gtk_text_buffer_get_selection_bounds (get_buffer (text_view),
                                                          NULL, NULL);
+
+  gtk_text_buffer_get_iter_at_mark (get_buffer (text_view),
+                                    &iter,
+                                    gtk_text_buffer_get_insert (get_buffer (text_view)));
+  
+  can_insert = gtk_text_iter_editable (&iter, text_view->editable);
   
   append_action_signal (text_view, text_view->popup_menu, _("Cut"), "cut_clipboard",
                         have_selection);
   append_action_signal (text_view, text_view->popup_menu, _("Copy"), "copy_clipboard",
                         have_selection);
+
   append_action_signal (text_view, text_view->popup_menu, _("Paste"), "paste_clipboard",
-                        TRUE);
+                        can_insert);
 
   menuitem = gtk_separator_menu_item_new ();
   gtk_widget_show (menuitem);